package com.harmontronics.hanma.paas.paas.interceptor;

import cn.hutool.json.JSONObject;
import com.harmontronics.hanma.paas.paas.annotation.Log;
import com.harmontronics.hanma.paas.paas.common.ResponseEntity;
import com.harmontronics.hanma.paas.paas.consts.BaseI18nKeyEnum;
import com.harmontronics.hanma.paas.paas.consts.DbConstants;
import com.harmontronics.hanma.paas.paas.domain.tenant.entity.HmOperationLog;
import com.harmontronics.hanma.paas.paas.domain.tenant.service.HmOperationLogService;
import com.harmontronics.hanma.paas.paas.exception.ErrorKeyException;
import com.harmontronics.hanma.paas.paas.token.ComposeTokenKit;
import com.harmontronics.hanma.paas.paas.token.MosTokenKit;
import com.harmontronics.hanma.paas.paas.token.TenantUserTokenKit;
import com.harmontronics.hanma.paas.paas.token.UserInfo;
import com.harmontronics.hanma.paas.paas.utils.RequestUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * @author ldb
 */
@Aspect
@Service
public class LogAspect {

    @Autowired
    private HmOperationLogService hmOperationLogService;

    @Autowired
    private TenantUserTokenKit tenantUserTokenKit;

    @Autowired
    private MosTokenKit mosTokenKit;

    @Value("${mos.oss.enabled:false}")
    private Boolean mosEnabled;

    @Pointcut("@annotation(com.harmontronics.hanma.paas.paas.annotation.Log)")
    public void logPointCut() {
    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {

        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        Log log = method.getAnnotation(Log.class);
        UserInfo userInfo = null;
        if(mosEnabled != null && mosEnabled){
            userInfo = mosTokenKit.getUserInfo();
        }else{
            userInfo = tenantUserTokenKit.getUserInfo();
        }

        String userName = userInfo.getUserName();
        HmOperationLog hmOperationLog = new HmOperationLog();
        hmOperationLog.setTenantUserId(userInfo.getUserId());
        hmOperationLog.setTenantUserName(userName);
        hmOperationLog.setOperationInfo(log.value());
        hmOperationLog.setCreateDate(LocalDateTime.now());
        String appUnique = RequestUtils.getAppUnique();
        if (!StringUtils.isEmpty(appUnique) && !DbConstants.DS_MASTER_NAME.equals(appUnique)) {
            hmOperationLog.setAppUnique(appUnique.split("_")[1]);
        }
        try {
            //请求的参数
            Object[] args = point.getArgs();
            if (args != null && args.length > 0) {
                Object arg0 = args[0];
                //删除接口用的是数组
                if(arg0.getClass().isArray()){
                    String str = Arrays.toString((Object[]) arg0);
                    hmOperationLog.setRequestJson(str);
                }else {
                    JSONObject reqJson = new JSONObject(args[0]);
                    hmOperationLog.setRequestJson(reqJson.toStringPretty());
                }
            }
            Object result = point.proceed();
            JSONObject rspJson = new JSONObject(result);
            hmOperationLog.setResponseJson(rspJson.toStringPretty());
            hmOperationLogService.save(hmOperationLog);
            return result;
        } catch (Exception ex) {
            if (ex instanceof ErrorKeyException) {
                ErrorKeyException e = (ErrorKeyException) ex;
                ResponseEntity<String> responseEntity = ResponseEntity.error(e.getErrorCode(), RequestUtils.localeMessage(e.getI18nKey(), e.getMessageData()), e.getMessageData());
                JSONObject rspJson = new JSONObject(responseEntity);
                hmOperationLog.setResponseJson(rspJson.toStringPretty());
                hmOperationLogService.save(hmOperationLog);
            } else if (ex instanceof DataAccessResourceFailureException) {
                ResponseEntity<String> responseEntity = ResponseEntity.error(BaseI18nKeyEnum.DB_QUERY_TIMEOUT);
                JSONObject rspJson = new JSONObject(responseEntity);
                hmOperationLog.setResponseJson(rspJson.toStringPretty());
                hmOperationLogService.save(hmOperationLog);
            } else {
                ResponseEntity<String> responseEntity = ResponseEntity.error(BaseI18nKeyEnum.SYSTEM_ERROR);
                JSONObject rspJson = new JSONObject(responseEntity);
                hmOperationLog.setResponseJson(rspJson.toStringPretty());
                hmOperationLogService.save(hmOperationLog);
            }

            throw ex;
        }
    }

}
